package org.jkuang.qstar.commons.io;

import java.nio.charset.Charset;

public class ByteReader {
	byte[] bs;
	int pos;
	static final Charset CHARSET = Charset.forName("utf8");

	public ByteReader(byte[] bs, int pos) {
		this.bs = bs;
		this.pos = pos;
	}

	public boolean hasElement() {
		return pos < bs.length;
	}

	public byte readByte() {
		return bs[pos++];
	}

	public short readShort() {
		return (short) (bs[pos++] << 8 & 0xff00 | bs[pos++] & 0xff);
	}

	public void reset() {
		this.pos = 0;
	}

	public void setPos(int pos) {
		this.pos = pos;
	}

	public void addOffset(int offset) {
		this.pos += offset;
	}

	public char readChar() {
		return (char) (bs[pos++] << 8 & 0xff00 | bs[pos++] & 0xff);
	}

	public int readInt() {
		return (bs[pos++] << 24) & 0xff000000 | (bs[pos++] << 16) & 0xff0000 | (bs[pos++] << 8) & 0xff00
				| bs[pos++] & 0xff;
	}

	public long readLong() {
		return ((bs[pos++] & 0xffl) << 56) | ((bs[pos++] & 0xffl) << 48) | ((bs[pos++] & 0xffl) << 40)
				| ((bs[pos++] & 0xffl) << 32) | ((bs[pos++] & 0xffl) << 24) | ((bs[pos++] & 0xffl) << 16)
				| ((bs[pos++] & 0xffl) << 8) | ((bs[pos++] & 0xffl) << 0);
	}

	public byte[] readBytes(int len) {
		byte[] data = new byte[len];
		System.arraycopy(bs, pos, data, 0, data.length);
		pos += data.length;
		return data;
	}

	public static int readInt(byte[] bs, int pos) {
		return (bs[pos] << 24) & 0xff000000 | (bs[pos + 1] << 16) & 0xff0000 | (bs[pos + 2] << 8) & 0xff00
				| bs[pos + 3] & 0xff;
	}

	public static long readLong(byte[] bs, int pos) {
		return ((bs[pos + 0] & 0xffl) << 56) | ((bs[pos + 1] & 0xffl) << 48) | ((bs[pos + 2] & 0xffl) << 40)
				| ((bs[pos + 3] & 0xffl) << 32) | ((bs[pos + 4] & 0xffl) << 24) | ((bs[pos + 5] & 0xffl) << 16)
				| ((bs[pos + 6] & 0xffl) << 8) | ((bs[pos + 7] & 0xffl) << 0);
	}

	public static short readShort(byte[] bs, int pos) {
		return (short) (bs[pos] << 8 & 0xff00 | bs[pos + 1] & 0xff);
	}

	public static char readChar(byte[] bs, int pos) {
		return (char) (bs[pos] << 8 & 0xff00 | bs[pos + 1] & 0xff);
	}

	public boolean hasMore(int len) {
		return this.bs.length - pos >= len;
	}

	public byte[] readShortBytes() {
		int len = readShort();
		return readBytes(len);
	}

	public String readShortString() {
		int len = readShort();
		return new String(readBytes(len), CHARSET);
	}

	public String readIntString() {
		int len = readInt();
		return new String(readBytes(len), CHARSET);
	}

	public byte[] readIntBytes() {
		int len = readInt();
		return readBytes(len);
	}

}
